/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package helloscala.practise.chapter4

abstract class Widget
class Button(label: String) extends Widget {
  def click: Unit = {
    //later to impl
  }
}

trait Subject {
  type Observer = {def receiveUpdate(subject: Any)}

  private var observers: List[Observer] = List()
  def addObserver(observer: Observer) = {observers ::= observer}
  def notifyObservers = observers foreach {_.receiveUpdate(this)}
}

class ObservableButton(name: String) extends Button(name) with Subject {
  override def click() = {
    super.click
    notifyObservers;
  }
}

class ButtonCountObserver {
  var count = 0
  def receiveUpdate(subject: Any) = {count += 1}
}

trait Clickable {
  def click()
}

//"with Clickable will get compile err"
trait ObservableClicks extends Clickable with Subject {
  //take note of "abstract" here, which tells the compiler that
  //the "click" function is not yet complete until an instance
  //which impl "click" is [clicked]
  //
  //"super" will be bound when this trait is [mixed into] an instance
  //that defines a concrete click method, such as Button
  abstract override def click = {
    super.click
    super.notifyObservers
  }
}

trait VetoableClicks extends Clickable {
  val maxAllowedClicks = 1
  private var count = 0

  abstract override def click = {
    if (count < maxAllowedClicks) {
      count += 1
      super.click
    }
  }
}

